package com.steve.summary.saga.编排式.service;

import com.steve.summary.saga.编排式.domain.OrderCancelledEvent;
import com.steve.summary.saga.编排式.domain.OrderCreatedEvent;
import com.steve.summary.saga.common.model.Order;
import com.steve.summary.saga.common.status.OrderStatus;
import com.steve.summary.saga.common.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Author: STEVE
 * @Description: 订单服务：负责订单的创建、取消和确认操作
 * @since: 2025-05-27
 */
@Service
public class OrderService {

    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    /**
     * 创建订单
     * 1. 保存订单到数据库
     * 2. 发布OrderCreatedEvent事件触发后续流程
     */
    @Transactional
    public void createOrder(Order order) {
        order.setStatus(OrderStatus.CREATED);
        orderRepository.save(order);
        eventPublisher.publishEvent(new OrderCreatedEvent(
                order.getId(),
                order.getUserId(),
                order.getProductId(),
                order.getAmount()
        ));
    }

    /**
     * 取消订单
     * 1. 更新订单状态为CANCELLED
     * 2. 发布OrderCancelledEvent事件触发补偿操作
     */
    @Transactional
    public void cancelOrder(Long orderId, String reason) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("Order not found"));
        order.setStatus(OrderStatus.CANCELLED);
        orderRepository.save(order);
        eventPublisher.publishEvent(new OrderCancelledEvent(orderId, reason));
    }

    /**
     * 确认订单
     * 将订单状态更新为CONFIRMED
     */
    @Transactional
    public void confirmOrder(Long orderId) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("Order not found"));
        order.setStatus(OrderStatus.CONFIRMED);
        orderRepository.save(order);
    }

}
